import config from '@/config'

// 增大zoom
export const zoom2Big = () => {
    const maxZoom = config.baseAppConfig.mapInitOptions.maxZoom ?? 18
    if (window.glMap.getZoom() <= maxZoom) {
        window.glMap.zoomTo(window.glMap.getZoom() + 1)
    }
}

// 缩小zoom
export const zoom2Small = () => {
    const minZoom = config.baseAppConfig.mapInitOptions.minZoom ?? 4
    if (window.glMap.getZoom() >= minZoom) {
        window.glMap.zoomTo(window.glMap.getZoom() - 1)
    }
}

// 重置地图配置
export const resetMapView = () => {
    window.glMap.flyTo(config.baseAppConfig.mapInitOptions)
}

// 切换2d/3d
export const switch23D = (type: '2d' | '3d') => {
    window.glMap.flyTo({
        pitch: type === '2d' ? 0 : 45,
        zoom: window.glMap.getZoom(),
        speed: 0.2,
        curve: 1,
    })
}

// 移除图层
export const removeLayer = (layerId: string) => {
    if (window.glMap.getLayer(layerId)) {
        window.glMap.removeLayer(layerId)
    }
}

// 移除数据
export const removeSource = (source: string) => {
    if (window.glMap.getSource(source)) {
        window.glMap.removeSource(source)
    }
}

// 同时移除图层和数据，仅仅使用在source名称和layer名称相同的情况
export const removeLayerAndSource = (layerId: string) => {
    removeLayer(layerId)
    removeSource(layerId)
}

// 显示图层
export const showLayer = (layerId: string) => {
    if (window.glMap && window.glMap.getLayer(layerId)) {
        window.glMap.setLayoutProperty(layerId, 'visibility', 'visible')
    }
}

// 隐藏图层
export const hideLayer = (layerId: string) => {
    if (window.glMap && window.glMap.getLayer(layerId)) {
        window.glMap.setLayoutProperty(layerId, 'visibility', 'none')
    }
}

// 打开地图弹窗
export const showMapPop = (params: {
    VueComponent: any // vue组件
    properties: Record<string, any> // vue组件的props属性
    coordinates: number[] // 坐标
    offset?: [number, number]
}) => {
    // 清理老的
    if (window.popContent) {
        window.popContent.unmount()
        window.popContent = null
    }
    // 打开弹窗
    if (window.glPop) {
        window.glPop.remove()
        window.glPop = null
    }
    // 实例化vue组件
    window.popContent = createApp(params.VueComponent, {
        properties: params.properties,
    })
    // 生成dom
    const parent = document.createElement('div')
    const $el = window.popContent.mount(parent).$el
    // 偏移位置
    const offset = params.offset || [0, -12]
    window.glMap.easeTo({
        center: [params.coordinates[0], params.coordinates[1]],
        speed: 0.2,
        curve: 1.0,
        offset: [0, 150],
    })
    // 构建弹窗
    window.glPop = new window.mapboxgl.Popup({
        closeOnClick: true,
        closeButton: false,
        offset,
        className: 'map-pop-style',
    })
        .setLngLat(params.coordinates)
        .setDOMContent($el)
        .setMaxWidth('none')
        .addTo(window.glMap)
    window.glPop.once('close', () => {
        removeMapPop()
    })
}

// 移除地图弹窗
export const removeMapPop = () => {
    if (window.popContent) {
        window.popContent.unmount()
        window.popContent = null
    }
    if (window.glPop) {
        window.glPop.remove()
        window.glPop = null
    }
}

// 添加点位滑动提示
export const addPointLayerHoverTip = (layerId: string, nameField = 'name') => {
    if (window.glMap && window.glMap.getLayer(layerId)) {
        const layer = window.glMap.getLayer(layerId)
        layer._tip_mouseenter_handler = (e: any) => {
            window.glMap.getCanvas().style.cursor = 'pointer'
            const coordinates = e.features[0].geometry.coordinates.slice()
            const description = e.features[0].properties[nameField]

            while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
                coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360
            }
            if (window.glTip) {
                window.glTip.remove()
            }
            window.glTip = new window.mapboxgl.Popup({
                className: 'map-tooltip-style',
                closeOnClick: false,
                closeButton: false,
            })
                .setLngLat(coordinates)
                .setHTML(description)
                .addTo(window.glMap)
            window.glMap.triggerRepaint()
        }
        window.glMap.on('mouseenter', layerId, layer._tip_mouseenter_handler)
        layer._tip_mouseleave_handler = () => {
            window.glMap.getCanvas().style.cursor = ''
            window.glTip.remove()
        }
        window.glMap.on('mouseleave', layerId, layer._tip_mouseleave_handler)
    }
}

// 移除滑动点位提示
export const removePointLayerHoverTip = (layerId: string) => {
    if (window.glMap && window.glMap.getLayer(layerId)) {
        const layer = window.glMap.getLayer(layerId)
        if (layer._tip_mouseenter_handler) {
            window.glMap.off('mouseenter', layerId, layer._tip_mouseenter_handler)
        }
        if (layer._tip_mouseleave_handler) {
            window.glMap.off('mouseleave', layerId, layer._tip_mouseleave_handler)
        }
    }
}

// 添加普通点位
export const addCommonPointLayer = (options: {
    layerId: string
    geojson: any
    onClick?: (e: any) => void
    hoverTipField?: string
}) => {
    // 添加数据资源
    window.glMap.addSource(options.layerId, {
        type: 'geojson',
        data: options.geojson,
    })
    // 添加图层资源
    const layer = window.glMap.addLayer({
        id: options.layerId,
        type: 'circle',
        source: options.layerId,
        paint: {
            'circle-radius': 10,
            'circle-color': 'red',
        },
    })
    // 添加图层点位点击事件
    if (layer._click_handler) {
        window.glMap.off('click', options.layerId, layer._click_handler)
    }
    layer._click_handler = (e: any) => {
        options.onClick && options.onClick(e)
    }
    window.glMap.on('click', options.layerId, layer._click_handler)
    // 添加鼠标提示
    removePointLayerHoverTip(options.layerId)
    addPointLayerHoverTip(options.layerId, options.hoverTipField ?? 'name')
}

// 组合型移除
export const removeCombinedLayers = (layerIds: string[]) => {
    layerIds.forEach(item => {
        const layer = window.glMap.getLayer(item)
        if (layer) {
            // 移除点击事件
            if (layer._click_handler) {
                window.glMap.off('click', item, layer._click_handler)
            }
            // 移除鼠标提示
            removePointLayerHoverTip(item)

            // 移除图层
            removeLayerAndSource(item)
        }
    })
}
